//
//  LwipChannelHandler.swift
//  Tunnel
//
//  Created by tgy on 2024/7/10.
//

import Foundation
import NIO
import CLwIP

struct LWIPAcceptEvent {
    let pcb: UnsafeMutablePointer<tcp_pcb>
}

struct LWIPDataEvent {
    let pcb: UnsafeMutablePointer<tcp_pcb>
    let data: ByteBuffer
}

final class LWIPHandler: ChannelInboundHandler {
    typealias InboundIn = ByteBuffer
    typealias OutboundOut = ByteBuffer

    private var context: ChannelHandlerContext?
    private let lwipEventLoop: EventLoop

    init(lwipEventLoop: EventLoop) {
        self.lwipEventLoop = lwipEventLoop
    }

//    func initializeLWIPCallbacks() {
//        // 示例：假设 lwip_tcp_accept 是你在 lwIP 中定义的回调函数
//        np_tcp_accept_callback = { (_: Optional<UnsafeMutableRawPointer>, pcb: Optional<UnsafeMutablePointer<tcp_pcb>>, err: Int) in
//            if let pcb = pcb {
//                self.triggerAcceptEvent(pcb: pcb)
//            }
//        }
//
//        // 示例：假设 lwip_tcp_recv 是你在 lwIP 中定义的回调函数
//        np_tcp_recv_callback = { (pcb: UnsafeMutableRawPointer?, pbuf: UnsafeMutableRawPointer?, err: Int) in
//            if let pcb = pcb, let pbuf = pbuf {
//                self.triggerDataEvent(pcb: pcb, pbuf: pbuf)
//            }
//        }
//    }

    private func triggerAcceptEvent(pcb: UnsafeMutablePointer<tcp_pcb>) {
        if let ctx = self.context {
            let event = LWIPAcceptEvent(pcb: pcb)
            ctx.eventLoop.execute {
                ctx.fireUserInboundEventTriggered(event)
            }
        }
    }
    
    private func triggerDataEvent(pcb: UnsafeMutablePointer<tcp_pcb>, pbuf: UnsafeMutablePointer<pbuf>) {
        if let ctx = self.context {
            // 假设 pbuf 是一个指向 pbuf 结构的指针，并且 len 是 pbuf 结构中的一个字段
            let pbufStruct = pbuf.pointee
            let data = ByteBufferAllocator().buffer(bytes: Data(bytes: pbufStruct.payload, count: Int(pbufStruct.len)))
            let event = LWIPDataEvent(pcb: pcb, data: data)
            ctx.eventLoop.execute {
                ctx.fireUserInboundEventTriggered(event)
            }
        }
    }

    func handlerAdded(context: ChannelHandlerContext) -> EventLoopFuture<Void> {
        self.context = context
//        initializeLWIPCallbacks()
        return context.eventLoop.makeSucceededFuture(())
    }

    func handlerRemoved(context: ChannelHandlerContext) {
        self.context = nil
    }

    func channelRead(context: ChannelHandlerContext, data: NIOAny) {
        let buffer = self.unwrapInboundIn(data)
        // 处理数据
    }
}


final class ProxyHandler: ChannelInboundHandler {
    typealias InboundIn = ByteBuffer
    typealias OutboundOut = ByteBuffer

    func userInboundEventTriggered(context: ChannelHandlerContext, event: Any) {
        if let acceptEvent = event as? LWIPAcceptEvent {
            print("New connection accepted: \(acceptEvent.pcb)")
            // 在这里处理新的连接
        } else if let dataEvent = event as? LWIPDataEvent {
            print("Data received from connection: \(dataEvent.pcb)")
            // 在这里处理接收到的数据，并转发到目标服务器
            forwardData(dataEvent.data, from: context)
        } else {
            context.fireUserInboundEventTriggered(event)
        }
    }

    private func forwardData(_ data: ByteBuffer, from context: ChannelHandlerContext) {
        let bootstrap = ClientBootstrap(group: context.eventLoop)
            .channelInitializer { channel in
                channel.pipeline.addHandler(ForwardingHandler(data: data))
            }
            .connect(host: "target-server.com", port: 80)

        bootstrap.whenComplete { result in
            switch result {
            case .success(let channel):
                print("Connected to target server")
            case .failure(let error):
                print("Failed to connect to target server: \(error)")
            }
        }
    }

    func channelRead(context: ChannelHandlerContext, data: NIOAny) {
        let buffer = self.unwrapInboundIn(data)
        // 处理数据
    }
}

final class ForwardingHandler: ChannelInboundHandler {
    typealias InboundIn = ByteBuffer
    typealias OutboundOut = ByteBuffer

    private let initialData: ByteBuffer

    init(data: ByteBuffer) {
        self.initialData = data
    }

    func channelActive(context: ChannelHandlerContext) {
        context.writeAndFlush(self.wrapOutboundOut(initialData), promise: nil)
    }

    func channelRead(context: ChannelHandlerContext, data: NIOAny) {
        let buffer = self.unwrapInboundIn(data)
        // 处理从目标服务器接收到的数据
    }
}
